package middleware

import (
	"fmt"
	"gin_demo/internal/consts"
	"gin_demo/internal/model"
	"gin_demo/utility"
	"github.com/gin-gonic/gin"
	"strconv"
	"strings"
	"time"
)

func CheckToken() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		// 判断token是否存在

		token := ctx.Request.Header.Get("Authorization")
		if token == "" {
			utility.Fail(ctx, "token不能为空")
			ctx.Abort()
			return
		}
		if strings.Split(token, " ")[0] != "Bearer" {
			utility.Fail(ctx, "token格式错误")
			ctx.Abort()
			return
		}
		// 校验token合法性
		mc, err := utility.ParseToken(strings.Split(token, " ")[1])
		if err != nil {
			utility.Fail(ctx, "token解析错误")
			ctx.Abort()
			return
		}
		// 判断过期时间
		if time.Now().Unix() > mc.ExpiresAt.Unix() {
			utility.Fail(ctx, "token授权过期")
			ctx.Abort()
			return
		}
		s, err := utility.RedisGet(mc.ID)
		if err != nil {
			fmt.Printf("err: %v\n", err)
			ctx.Abort()
			return
		}
		// 判断redis和当前token是否一致
		if s != strings.Split(token, " ")[1] {
			utility.Fail(ctx, "token无效")
			ctx.Abort()
			return
		}
		// 判断token过期续签
		// mc.ExpiresAt.Time.
		h, _ := time.ParseDuration("-1h")
		t := mc.ExpiresAt.Time.Add(1 * h) // 过期时间减去一小时
		nowUnix := time.Now().Unix()
		if nowUnix > t.Unix() {
			user := model.AdminInfo{
				ID:       mc.TokenInfo.Id,
				UserName: mc.TokenInfo.UserName,
				RoleIds:  mc.TokenInfo.RoleIds,
				IsAdmin:  mc.TokenInfo.IsAdmin,
			}
			tokenStr, _ := utility.CreateToken(user)
			utility.RedisSet(strconv.Itoa(int(mc.TokenInfo.Id)), tokenStr)
			ctx.Header("newToken", tokenStr)
			CtxAccountId := mc.TokenInfo.RoleIds
			CtxAccountName := mc.TokenInfo.UserName
			CtxAccountStatus := mc.TokenInfo.Status
			CtxAccountIsAdmin := mc.TokenInfo.IsAdmin
			CtxAccountRoleIds := mc.TokenInfo.RoleIds
			ctx.Set("CtxAccountId", CtxAccountId)
			ctx.Set("CtxAccountName", CtxAccountName)
			ctx.Set("CtxAccountStatus", CtxAccountStatus)
			ctx.Set("CtxAccountIsAdmin", CtxAccountIsAdmin)
			ctx.Set("CtxAccountRoleIds", CtxAccountRoleIds)
			if mc.TokenInfo.IsAdmin {
				ctx.Next()
			} else {
				// 使用role.role_ids转为uint查询权限和角色关联表，看是否匹配权限
				id, _ := strconv.ParseUint(mc.TokenInfo.RoleIds, 10, 64)
				fmt.Printf("id: %v\n", id)
				rp := []model.RolePermissions{}
				tx := consts.App.DB.Where("role_id=?", id).Find(&rp)
				if tx.Error != nil || tx.RowsAffected == 0 {
					utility.Fail(ctx, "权限不足，无法访问")
					ctx.Abort()
				} else {
					ctx.Next()
				}
			}
			ctx.Next()

		} else {
			CtxAccountId := mc.TokenInfo.RoleIds
			CtxAccountName := mc.TokenInfo.UserName
			CtxAccountStatus := mc.TokenInfo.Status
			CtxAccountIsAdmin := mc.TokenInfo.IsAdmin
			CtxAccountRoleIds := mc.TokenInfo.RoleIds
			ctx.Set("CtxAccountId", CtxAccountId)
			ctx.Set("CtxAccountName", CtxAccountName)
			ctx.Set("CtxAccountStatus", CtxAccountStatus)
			ctx.Set("CtxAccountIsAdmin", CtxAccountIsAdmin)
			ctx.Set("CtxAccountRoleIds", CtxAccountRoleIds)
			if mc.TokenInfo.IsAdmin {
				ctx.Next()
			} else {
				// 使用role.role_ids转为uint查询权限和角色关联表，看是否匹配权限
				id, _ := strconv.ParseUint(mc.TokenInfo.RoleIds, 10, 64)
				rp := []model.RolePermissions{}
				tx := consts.App.DB.Where("role_id=?", id).Find(&rp)
				if tx.Error != nil || tx.RowsAffected == 0 {
					utility.Fail(ctx, "权限不足，无法访问")
					ctx.Abort()
				} else {
					ctx.Next()
				}
			}
		}

	}
}
